home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvipage / fonts.c < prev    next >
C/C++ Source or Header  |  1992-05-11  |  31KB  |  1,336 lines

  1. /*
  2.  * dvipage: DVI Previewer Program for Suns
  3.  *
  4.  * Neil Hunt (hunt@spar.slb.com)
  5.  *
  6.  * This program is based, in part, upon the program dvisun,
  7.  * distributed by the UnixTeX group, extensively modified by
  8.  * Neil Hunt at the Schlumberger Palo Alto Research Laboratories
  9.  * of Schlumberger Technologies, Inc.
  10.  *
  11.  * Copyright (c) 1988 Schlumberger Technologies, Inc 1988.
  12.  * Anyone can use this software in any manner they choose,
  13.  * including modification and redistribution, provided they make
  14.  * no charge for it, and these conditions remain unchanged.
  15.  *
  16.  * This program is distributed as is, with all faults (if any), and
  17.  * without any warranty. No author or distributor accepts responsibility
  18.  * to anyone for the consequences of using it, or for whether it serves any
  19.  * particular purpose at all, or any other reason.
  20.  *
  21.  * $Log:    fonts.c,v $
  22.  * Revision 1.1  88/11/28  18:40:54  hunt
  23.  * Initial revision
  24.  * 
  25.  * Stripped out of dvipage 1.4,
  26.  * with additions from mitdrivers from TeX 1988 distribution tape.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <sys/param.h>        /* For MAXPATHLEN */
  31. #include <fcntl.h>
  32. #include <suntool/sunview.h>
  33. #include "dvipage.h"
  34. #include "dvi.h"
  35.  
  36. forward FILE *            open_font_file();
  37.  
  38. forward bool            init_font_file();
  39. forward bool            read_font_char();
  40.  
  41. static int            nopen = 0;    /* number of open FNT files */
  42.  
  43. /*
  44.  * get_font_def:
  45.  *    Read the font definitions as they are in the postamble of the DVI file.
  46.  *    Returns TRUE unless the document can not be processed further.
  47.  */
  48.  
  49. bool
  50. get_font_def()
  51. {
  52.     char *calloc ();
  53.     unsigned char   byte;
  54.  
  55.     while(((byte = get_unsigned(dvifp, 1)) >= FNT_DEF1) &&
  56.       (byte <= FNT_DEF4))
  57.     {
  58.         switch (byte)
  59.         {
  60.         case FNT_DEF1:
  61.             if(! read_font_def(get_unsigned(dvifp, 1)))
  62.                 return FALSE;
  63.             break;
  64.  
  65.         case FNT_DEF2:
  66.             if(! read_font_def(get_unsigned(dvifp, 2)))
  67.                 return FALSE;
  68.             break;
  69.  
  70.         case FNT_DEF3:
  71.             if(! read_font_def(get_unsigned(dvifp, 3)))
  72.                 return FALSE;
  73.             break;
  74.  
  75.         case FNT_DEF4:
  76.             if(! read_font_def(get_unsigned(dvifp, 4)))
  77.                 return FALSE;
  78.             break;
  79.  
  80.         default:
  81.             message(
  82.   "%s: Bad dvi file: bad font specification.", filename);
  83.             return FALSE;
  84.         }
  85.     }
  86.     if(byte != POST_POST)
  87.     {
  88.         message(
  89.   "%s: Bad dvi file: no postpostamble after fontdefs.", filename);
  90.         return FALSE;
  91.     }
  92.  
  93.     return TRUE;
  94. }
  95.  
  96. /*
  97.  * skip_font_def:
  98.  *    Ignore font definition when fonts have been read from the postamble.
  99.  */
  100.  
  101. /* ARGSUSED */
  102. void
  103. skip_font_def(k)
  104. int k;
  105. {
  106.     int a, l;
  107.  
  108.     (void)get_unsigned(dvifp, 4);
  109.     (void)get_unsigned(dvifp, 4);
  110.     (void)get_unsigned(dvifp, 4);
  111.     a = get_unsigned(dvifp, 1);
  112.     l = get_unsigned(dvifp, 1);
  113.     fseek(dvifp, (long)a+l, 1);
  114. }
  115.  
  116. /*
  117.  * read_font_def:
  118.  *    Reads font def, and attempts to open font file and read data.
  119.  *    Returns TRUE unless a fatal error has occurred so that
  120.  *    document processing cannot proceed.
  121.  */
  122.  
  123. bool
  124. read_font_def(k)
  125. int k;
  126. {
  127.     int i;
  128.     struct char_entry *tcharptr;
  129.     FILE *font_fp;
  130.  
  131.     /*
  132.      * Allocate and link new font entry.
  133.      */
  134.     if((fontptr =
  135.       (struct font_entry *)calloc(1, sizeof(struct font_entry))) == NULL)
  136.     {
  137.         message(
  138.           "Out of memory for font entries; try a larger machine.");
  139.         return FALSE;
  140.     }
  141.     fontptr->next = hfontptr;
  142.     hfontptr = fontptr;
  143.  
  144.     /*
  145.      * Fill in new font entry.
  146.      */
  147.     fontptr->font_file_fd = NULL;
  148.     fontptr->k = k;
  149.     fontptr->c = get_unsigned(dvifp, 4); /* checksum */
  150.     fontptr->s = get_unsigned(dvifp, 4); /* space size */
  151.     fontptr->d = get_unsigned(dvifp, 4); /* design size */
  152.     fontptr->a = get_unsigned(dvifp, 1); /* area length for font name */
  153.     fontptr->l = get_unsigned(dvifp, 1); /* device length */
  154.     fread(fontptr->n, 1, fontptr->a+fontptr->l, dvifp);
  155.     fontptr->n[fontptr->a+fontptr->l] = '\0';
  156.     fontptr->font_space = fontptr->s/6; /* never used */
  157.     fontptr->font_gf_mag = (int)((actual_factor((int)(((float)fontptr->s/
  158.       (float)fontptr->d)*1000.0 + 0.5)) *
  159. #ifdef USEGLOBALMAG
  160.       actual_factor(mag) *
  161. #endif
  162.       (float)resolution) + 0.5);
  163.     fontptr->font_pxl_mag = (int)((actual_factor((int)(((float)fontptr->s/
  164.       (float)fontptr->d)*1000.0 + 0.5)) *
  165. #ifdef USEGLOBALMAG
  166.       actual_factor(mag) *
  167. #endif
  168.       (float)resolution * 5.0) + 0.5);
  169.  
  170.     /*
  171.      * Try to find the font file to match.
  172.      */
  173.     if(! find_font_file(font_path, fontptr) ||
  174.       (font_fp = open_font_file(fontptr)) == NO_FILE)
  175.     {
  176.         message("Cant find or open font file \"%s\" .%dgf or .%dpxl",
  177.           fontptr->n, fontptr->font_gf_mag, fontptr->font_pxl_mag);
  178.         if(verbose & DEBUG_FONTS)
  179.             fprintf(stderr,
  180.               "Cant find font file %s %s .%dgf or .%dpxl\n",
  181.                 font_path, fontptr->n,
  182.                 fontptr->font_gf_mag, fontptr->font_pxl_mag);
  183.  
  184.         fontptr->font_file_fd = NO_FILE;
  185.         fontptr->magnification = 0;
  186.         fontptr->designsize = 0;
  187.         for(i = 0; i < NFNTCHARS; i++)
  188.         {
  189.             tcharptr = &(fontptr->ch[i]);
  190.             tcharptr->width = 0;
  191.             tcharptr->height = 0;
  192.             tcharptr->xOffset = 0;
  193.             tcharptr->yOffset = 0;
  194.             tcharptr->where.isloaded = FALSE;
  195.             tcharptr->where.address.fileOffset = NONEXISTENT;
  196.             tcharptr->tfmw = 0;
  197.         }
  198.  
  199.         return TRUE;
  200.     }
  201.     else
  202.         return init_font_file(font_fp, fontptr);
  203. }
  204.  
  205. /*
  206.  * open_font_file:
  207.  *    Called with fontptr; opens a file for this font.
  208.  *    May have to close another to do it.
  209.  *    Returns a FILE * pointer, or NO_FILE.
  210.  */
  211.  
  212. FILE *
  213. open_font_file(fontptr)
  214. struct font_entry *fontptr;
  215. {
  216.     register struct font_entry *tfontptr, *lufontptr;
  217.     register int used;
  218.  
  219.     if(nopen >= MAXOPEN)
  220.     {
  221.         used = MAXINT;
  222.         lufontptr = NULL;
  223.         for(tfontptr = hfontptr; tfontptr; tfontptr = tfontptr->next)
  224.         {
  225.             if(tfontptr->font_file_fd == NO_FILE ||
  226.               tfontptr->font_file_fd == NULL ||
  227.               tfontptr == fontptr)
  228.                 continue;
  229.  
  230.             if(tfontptr->use_count < used)
  231.             {
  232.                 used = tfontptr->use_count;
  233.                 lufontptr = tfontptr;
  234.             }
  235.         }
  236.  
  237.         if(lufontptr == NULL)
  238.         {
  239.             fprintf(stderr, "Cant have no least used font\n");
  240.             exit(1);
  241.         }
  242.  
  243.         if(verbose & DEBUG_FONTS)
  244.             fprintf(stderr, "Closing (%x) font '%s'\n",
  245.               lufontptr->font_file_fd, lufontptr->name);
  246.         fclose(lufontptr->font_file_fd);
  247.         lufontptr->font_file_fd = NULL;
  248.         --nopen;
  249.     }
  250.  
  251.     /*
  252.      * Open the file; close-on-exec.
  253.      */
  254.     if((fontptr->font_file_fd = fopen(fontptr->name, "r")) == NULL)
  255.     {
  256.         message("Cant open font file %s", fontptr->name);
  257.         fontptr->font_file_fd = NO_FILE;
  258.     }
  259.     else
  260.     {
  261.         if(verbose & DEBUG_FONTS)
  262.             fprintf(stderr, "Opened (%x) font '%s'\n",
  263.               fontptr->font_file_fd, fontptr->name);
  264.         fcntl(fileno(fontptr->font_file_fd),  F_SETFD,  1);
  265.         nopen++;
  266.     }
  267.  
  268.     return fontptr->font_file_fd;
  269. }
  270.  
  271. /*
  272.  * close_fonts:
  273.  *    Closes all the font files, and frees up all the memory.
  274.  */
  275.  
  276. void
  277. close_fonts()
  278. {
  279.     register struct font_entry *pf, *next;
  280.     register struct pixrect *pr;
  281.     register int i;
  282.  
  283.     for(pf = hfontptr; pf; pf = next)
  284.     {
  285.         if(verbose & DEBUG_FONTS)
  286.             fprintf(stderr, "Freeing font %s\n", pf->name);
  287.  
  288.         /*
  289.          * Close the file if still open.
  290.          */
  291.         if(pf->font_file_fd != NO_FILE && pf->font_file_fd != NULL)
  292.         {
  293.             fclose(pf->font_file_fd);
  294.             --nopen;
  295.         }
  296.         pf->font_file_fd = NULL;
  297.  
  298.         /*
  299.          * Free the pixrects.
  300.          */
  301.         for(i = 0; i < NFNTCHARS; i++)
  302.         {
  303.             if(pf->ch[i].where.isloaded == TRUE)
  304.             {
  305.                 if(pr = pf->ch[i].where.address.pixrectptr)
  306.                     pr_destroy(pr);
  307.             }
  308.         }
  309.  
  310.         /*
  311.          * Get the next.
  312.          */
  313.         next = pf->next;
  314.  
  315.         free(pf);
  316.     }
  317.  
  318.     hfontptr = NULL;
  319.     fontptr = NULL;
  320.  
  321.     if(nopen != 0)
  322.     {
  323.         fprintf(stderr, "Mislaid some font files; cant happen\n");
  324.         exit(1);
  325.     }
  326. }
  327.  
  328. /*
  329.  * load_char:
  330.  *    Reads in a character from the font file.
  331.  *    Returns TRUE unless document cannot be processed.
  332.  */
  333.  
  334. bool
  335. load_char(fontptr, ptr)
  336. struct font_entry *fontptr;
  337. struct char_entry *ptr;
  338. {
  339.     register FILE *font_fp;
  340.  
  341.     if(verbose & DEBUG_CHARS)
  342.         fprintf(stderr, "Load char %d of font %s at offset %d\n",
  343.           (ptr - &fontptr->ch[0]), fontptr->name,
  344.           ptr->where.address.fileOffset);
  345.  
  346.     /*
  347.      * If the font file is currently unopen, then open it.
  348.      */
  349.     if((font_fp = fontptr->font_file_fd) == NULL)
  350.         font_fp = open_font_file(fontptr);
  351.  
  352.     /*
  353.      * If the font file is unavailable, forget it.
  354.      */
  355.     if(font_fp == NO_FILE)
  356.     {
  357.         ptr->where.isloaded = TRUE;
  358.         return TRUE;
  359.     }
  360.  
  361.     /*
  362.      * Read the font character.
  363.      */
  364.     return read_font_char(font_fp, fontptr, ptr);
  365. }
  366.  
  367. /*
  368.  * Generic Font reading functions.
  369.  * ==============================
  370.  */
  371.  
  372. forward bool        init_gf_font_file();
  373. forward bool        init_pxl_font_file();
  374. forward bool        init_pk_font_file();
  375. forward bool        read_gf_font_char();
  376. forward bool        read_pxl_font_char();
  377. forward bool        read_pk_font_char();
  378.  
  379. /*
  380.  * init_font_file:
  381.  *    Reads general data from font file.
  382.  *    Returns TRUE unless processing cannot continue.
  383.  */
  384.  
  385. bool
  386. init_font_file(font_fp, fontptr)
  387. FILE *font_fp;
  388. struct font_entry *fontptr;
  389. {
  390.     switch(fontptr->type)
  391.     {
  392.     case TYPE_GF:
  393.         return init_gf_font_file(font_fp, fontptr);
  394.  
  395.     case TYPE_PXL:
  396.         return init_pxl_font_file(font_fp, fontptr);
  397.  
  398.     case TYPE_PK:
  399.         return init_pk_font_file(font_fp, fontptr);
  400.  
  401.     default:
  402.         fprintf(stderr, "Unknown type of font file; cant happen\n");
  403.         exit(1);
  404.     }
  405. }
  406.  
  407. /*
  408.  * read_font_char:
  409.  *    Reads character from font file.
  410.  *    Returns TRUE unless document cannot be processed.
  411.  */
  412.  
  413. bool
  414. read_font_char(font_fp, fontptr, ptr)
  415. FILE *font_fp;
  416. struct font_entry *fontptr;
  417. struct char_entry *ptr;
  418. {
  419.     switch(fontptr->type)
  420.     {
  421.     case TYPE_GF:
  422.         return read_gf_font_char(font_fp, fontptr, ptr);
  423.  
  424.     case TYPE_PXL:
  425.         return read_pxl_font_char(font_fp, fontptr, ptr);
  426.  
  427.     case TYPE_PK:
  428.         return read_pk_font_char(font_fp, fontptr, ptr);
  429.  
  430.     default:
  431.         fprintf(stderr, "Unknown type of font file; cant happen\n");
  432.         exit(1);
  433.     }
  434. }
  435.  
  436. /*
  437.  * GF font reading functions.
  438.  * ==========================
  439.  */
  440.  
  441. #define false    0
  442. #define true    1
  443.  
  444. /* The following macros describe gf file format */
  445.  
  446. #define paint_0        0
  447. #define last_paint    63
  448. #define paint1        64
  449. #define paint2        65
  450. #define paint3        66
  451. #define boc        67
  452. #define boc1        68
  453. #define eoc        69
  454. #define skip0        70
  455. #define skip1        71
  456. #define skip2        72
  457. #define skip3        73
  458. #define new_row_0    74
  459. #define last_new_row    238
  460. #define xxx1        239
  461. #define xxx2        240
  462. #define xxx3        241
  463. #define xxx4        242
  464. #define yyy        243
  465. #define no_op        244
  466. #define char_loc    245
  467. #define char_loc0    246
  468. #define pre        247
  469. #define post        248
  470. #define postpost    249
  471. #define undefined_cases    250: case 251: case 252: case 253: case 254: case 255
  472. #define gf_version    131
  473.  
  474. /*
  475.  * init_gf_font_file:
  476.  *    Reads font data from file.
  477.  *    If the file is unavailable, its fp is set to NO_FILE.
  478.  *    Returns TRUE unless processing cannot continue.
  479.  */
  480.  
  481. bool
  482. init_gf_font_file(font_fp, fontptr)
  483. FILE *font_fp;
  484. struct font_entry *fontptr;
  485. {
  486.     register int b, c;
  487.     register struct char_entry *tcharptr;
  488.  
  489.     long checksum;        /* should match TFM file and DVI file */
  490.     long hppp, vppp;    /* horizontal and vertical pixels/point scaled
  491.                  * 1<<16 */
  492.     int font_min_m, font_max_m, font_min_n, font_max_n;
  493.     int char_wd;        /* character width in pixels, rounded if
  494.                  * necessary */
  495.  
  496.     /*
  497.      * Seek to the postamble part of the GF file.
  498.      */
  499.     fseek(font_fp, -5L, 2);    /* skip four 223's */
  500.     do
  501.     {
  502.         c = get_unsigned(font_fp, 1);
  503.         fseek(font_fp, -2L, 1);
  504.     } while(c == 223);
  505.  
  506.     if(c != gf_version)
  507.     {
  508.         message("Bad GF font version number (%d) in %s.",
  509.           c, fontptr->name);
  510.         fclose(fontptr->font_file_fd);
  511.         fontptr->font_file_fd = NO_FILE;
  512.         return TRUE;
  513.     }
  514.  
  515.     fseek(font_fp, -3L, 1);    /* back up to the pointer */
  516.     if(fseek(font_fp, (long)get_unsigned(font_fp, 4), 0) < 0 ||
  517.       get_unsigned(font_fp, 1) != post)
  518.     {
  519.         message("Bad GF font file format in %s.", fontptr->name);
  520.         fclose(fontptr->font_file_fd);
  521.         fontptr->font_file_fd = NO_FILE;
  522.         return TRUE;
  523.     }
  524.  
  525.     (void)get_unsigned(font_fp, 4);    /* ignore back pointer to font-wide xxx
  526.                      * commands */
  527.     fontptr->designsize = get_unsigned(font_fp, 4);
  528.     checksum = get_unsigned(font_fp, 4);
  529.     hppp = get_unsigned(font_fp, 4);
  530.     vppp = get_unsigned(font_fp, 4);
  531.     font_min_m = get_unsigned(font_fp, 4);
  532.     font_max_m = get_unsigned(font_fp, 4);
  533.     font_min_n = get_unsigned(font_fp, 4);
  534.     font_max_n = get_unsigned(font_fp, 4);
  535.  
  536.     if(verbose & DEBUG_FONTS)
  537.         fprintf(stderr, "Initialising font %s\n", fontptr->name);
  538.  
  539.     for(tcharptr = &fontptr->ch[0]; tcharptr < &fontptr->ch[NFNTCHARS];
  540.       tcharptr++)
  541.     {
  542.         tcharptr->where.isloaded = FALSE;
  543.         tcharptr->where.address.fileOffset = -1;
  544.         tcharptr->tfmw = 0;
  545.     }
  546.     for(;;)
  547.     {
  548.         b = get_unsigned(font_fp, 1);
  549.         c = get_unsigned(font_fp, 1);
  550.  
  551.         if(verbose & DEBUG_CHARS)
  552.             fprintf(stderr, "Finding char %d type %d\n", c, b);
  553.  
  554.         if(b == char_loc0)
  555.             char_wd = get_unsigned(font_fp, 1);
  556.         else if(b == char_loc)
  557.         {
  558.             char_wd = (get_unsigned(font_fp, 4) + 0100000) >> 16;
  559.             get_unsigned(font_fp, 4);    /* skip dy */
  560.         }
  561.         else
  562.             break;
  563.  
  564.         tcharptr = &(fontptr->ch[c % NFNTCHARS]);
  565.         tcharptr->tfmw =
  566.           ((float)get_unsigned(font_fp, 4) * (float)fontptr->s) /
  567.           (float)(1 << 20);
  568.         tcharptr->where.address.fileOffset = get_unsigned(font_fp, 4);
  569.     }
  570.  
  571.     if((fontptr->c != 0) && (checksum != 0) && (fontptr->c != checksum))
  572.         message("Bad font checksum %d != %d, font %s.",
  573.           checksum, fontptr->c, fontptr->name);
  574.  
  575.     /*
  576.      * Return leaving font file open for use.
  577.      */
  578.     return TRUE;
  579. }
  580.  
  581. /*
  582.  * read_font_char:
  583.  *    Reads character from font file.
  584.  *    Returns TRUE unless document cannot be processed.
  585.  */
  586.  
  587. bool
  588. read_gf_font_char(font_fp, fontptr, ptr)
  589. FILE *font_fp;
  590. struct font_entry *fontptr;
  591. register struct char_entry *ptr;
  592. {
  593.     register int i, b, c;
  594.     register int x, y;
  595.     register struct pixrect *pr;
  596.     int min_m, max_m, min_n, max_n;
  597.     int bytes, lines, paint_switch;
  598.     long backpointer;
  599.     long charfam;
  600.  
  601.     if(verbose & DEBUG_CHARS)
  602.         fprintf(stderr, "Reading char %d of font %s\n",
  603.           (ptr - &fontptr->ch[0]), fontptr->name);
  604.  
  605.     /*
  606.      * Seek to start of char.
  607.      */
  608.     fseek(font_fp, (long)ptr->where.address.fileOffset, 0);
  609.  
  610.     /*
  611.      * Sync with char
  612.      */
  613.     do
  614.     {
  615.         switch(i = get_unsigned(font_fp, 1))
  616.         {
  617.         case yyy:
  618.             (void)get_unsigned(font_fp, 1);
  619.             /* FALLTHROUGH */
  620.         case paint3:
  621.         case skip3:
  622.             (void)get_unsigned(font_fp, 1);
  623.             /* FALLTHROUGH */
  624.         case paint2:
  625.         case skip2:
  626.             (void)get_unsigned(font_fp, 1);
  627.             /* FALLTHROUGH */
  628.         case paint1:
  629.         case skip1:
  630.             (void)get_unsigned(font_fp, 1);
  631.             break;
  632.  
  633.         case boc:
  634.         case boc1:
  635.             break;
  636.  
  637.         case pre:
  638.             if((c = get_unsigned(font_fp, 1)) != gf_version)
  639.             {
  640.                 message(
  641.                   "Bad GF font version number (%d); font %s.",
  642.                   c, fontptr->name);
  643.                 return TRUE;
  644.             }
  645.             fseek(font_fp, (long)get_unsigned(font_fp, 1), 1);
  646.             break;
  647.  
  648.         case xxx1:
  649.             fseek(font_fp, (long)get_unsigned(font_fp, 1), 1);
  650.             break;
  651.  
  652.         case xxx2:
  653.             fseek(font_fp, (long)get_unsigned(font_fp, 2), 1);
  654.             break;
  655.  
  656.         case xxx3:
  657.             fseek(font_fp, (long)get_unsigned(font_fp, 3), 1);
  658.             break;
  659.  
  660.         case xxx4:
  661.             fseek(font_fp, (long)get_unsigned(font_fp, 4), 1);
  662.             break;
  663.  
  664.         case post:
  665.             if(verbose & DEBUG_FONTS)
  666.                 fprintf(stderr, "gettochar: found POST\n");
  667.             return TRUE;
  668.  
  669.         case char_loc:
  670.         case char_loc0:
  671.         case postpost:
  672.         case undefined_cases:
  673.             message(
  674.               "Bad GF font file format (%d); font %s.",
  675.               i, fontptr->name);
  676.             return TRUE;
  677.  
  678.         default: /* do nothing */ ;
  679.             break;
  680.         }
  681.  
  682.         if(i != boc && i != boc1 &&
  683.           verbose & DEBUG_FONTS)
  684.             fprintf(stderr, "gettochar iterates with %d\n", i);
  685.     }
  686.     while(i != boc && i != boc1);
  687.  
  688.     /*
  689.      * Read character code and raster sizes.
  690.      */
  691.     switch(i)
  692.     {
  693.     case boc:
  694.         c = get_unsigned(font_fp, 4);
  695.         backpointer = get_unsigned(font_fp, 4);
  696.         min_m = get_unsigned(font_fp, 4);
  697.         max_m = get_unsigned(font_fp, 4);
  698.         min_n = get_unsigned(font_fp, 4);
  699.         max_n = get_unsigned(font_fp, 4);
  700.         charfam = c < 0 ? -((-c) >> 8) : c >> 8;
  701.         break;
  702.  
  703.     case boc1:
  704.         c = get_unsigned(font_fp, 1);
  705.         x = get_unsigned(font_fp, 1);    /* del_m */
  706.         max_m = get_unsigned(font_fp, 1);
  707.         min_m = max_m - x;
  708.         x = get_unsigned(font_fp, 1);    /* del_n */
  709.         max_n = get_unsigned(font_fp, 1);
  710.         min_n = max_n - x;
  711.         break;
  712.  
  713.     default:
  714.         fprintf(stderr,
  715.           "Font BOC code has corrupted in memory; cant happen.\n");
  716.         exit(1);
  717.     }
  718.     ptr->width = max_m - min_m + 1;
  719.     ptr->height = max_n - min_n + 1;
  720.     ptr->xOffset = -min_m;
  721.     ptr->yOffset = max_n;
  722.  
  723.     /*
  724.      * Create Pixrect for char.
  725.      * Clear to zero.
  726.      */
  727.     pr = mem_create(ptr->width, ptr->height, 1);
  728.     ptr->where.address.pixrectptr = pr;
  729.     pr_rop(pr, 0, 0, ptr->width, ptr->height, PIX_SRC | PIX_COLOR(0),
  730.       NULL, 0, 0);
  731. #ifdef NEVER
  732.     pr_rop(pr, 0, 0, ptr->width, ptr->height, PIX_SRC | PIX_COLOR(1),
  733.       NULL, 0, 0);
  734.     pr_rop(pr, 1, 1, ptr->width-2, ptr->height-2, PIX_SRC | PIX_COLOR(0),
  735.       NULL, 0, 0);
  736. #endif NEVER
  737.     x = 0;
  738.     y = 0;
  739.     paint_switch = 0;
  740.  
  741.     for(;;)
  742.     {
  743.         switch(b = get_unsigned(font_fp, 1))
  744.         {
  745.         case paint1:
  746.             bytes = get_unsigned(font_fp, 1);
  747.             goto paint;
  748.  
  749.         case paint2:
  750.             bytes = get_unsigned(font_fp, 2);
  751.             goto paint;
  752.  
  753.         case paint3:
  754.             bytes = get_unsigned(font_fp, 3);
  755.             goto paint;
  756.  
  757.         case skip0:
  758.             lines = 0;
  759.             goto skip;
  760.  
  761.         case skip1:
  762.             lines = get_unsigned(font_fp, 1);
  763.             goto skip;
  764.  
  765.         case skip2:
  766.             lines = get_unsigned(font_fp, 2);
  767.             goto skip;
  768.  
  769.         case skip3:
  770.             lines = get_unsigned(font_fp, 3);
  771.             goto skip;
  772.  
  773.         case xxx1:
  774.             fseek(font_fp, (long)get_unsigned(font_fp, 1), 1);
  775.             continue;
  776.  
  777.         case xxx2:
  778.             fseek(font_fp, (long)get_unsigned(font_fp, 2), 1);
  779.             continue;
  780.  
  781.         case xxx3:
  782.             fseek(font_fp, (long)get_unsigned(font_fp, 3), 1);
  783.             continue;
  784.  
  785.         case xxx4:
  786.             fseek(font_fp, (long)get_unsigned(font_fp, 4), 1);
  787.             continue;
  788.  
  789.         case yyy:
  790.             get_unsigned(font_fp, 4);
  791.             continue;
  792.  
  793.         case no_op:
  794.             continue;
  795.  
  796.         case eoc:
  797.             ptr->where.isloaded = TRUE;
  798.             return TRUE;
  799.  
  800.         default:
  801.             if(b >= paint_0 && b <= last_paint)
  802.             {
  803.                 bytes = b - paint_0;
  804.  
  805. paint:;                /*
  806.                  * Paint the specified number of bytes black
  807.                  *    or white.
  808.                  * Toggle the paint colour.
  809.                  * Advance the current position.
  810.                  */
  811.                 if(verbose & DEBUG_CHARS)
  812.                     fprintf(stderr,
  813.   "  Paint %d line %d, %d for %d\n",  paint_switch, y, x, bytes);
  814.                 if(bytes > 0 && paint_switch)
  815.                     pr_rop(pr, x, y, bytes, 1,
  816.                       PIX_SRC | PIX_COLOR(1), NULL, 0, 0);
  817.                 paint_switch = ! paint_switch;
  818.                 x += bytes;
  819.                 continue;
  820.             }
  821.             else if(b >= new_row_0 && b <= last_new_row)
  822.             {
  823.                 /*
  824.                  * Special shortcut; skip to new row,
  825.                  * and paint some white bytes.
  826.                  * Leave switch ready for next black bytes.
  827.                  */
  828.                 y++;
  829.                 x = b - new_row_0;
  830.                 paint_switch = 1;
  831.                 if(verbose & DEBUG_CHARS)
  832.                     fprintf(stderr,
  833.   "  Jump to line %d, paint white to %d\n", y, x);
  834.                 continue;
  835.             }
  836.             else
  837.             {
  838.                 message(
  839.   "Bad GF file format code %d; char %d font %s.",
  840.                   b, (ptr - &fontptr->ch[0]), fontptr->name);
  841.                 return TRUE;
  842.             }
  843.  
  844. skip:;            /*
  845.              * Skip to the start of the line.th next line.
  846.              * Start at beginnning of line, ready to paint white.
  847.              */
  848.             y += lines + 1;
  849.             x = 0;
  850.             paint_switch = 0;
  851.             if(verbose & DEBUG_CHARS)
  852.                 fprintf(stderr,
  853.   "  Jump to line %d at start\n", y);
  854.             continue;
  855.         }
  856.     }
  857. }
  858.  
  859. /*
  860.  * PXL font reading functions.
  861.  * ==========================
  862.  */
  863.  
  864. #define NPXLCHARS    128
  865.  
  866. /*
  867.  * init_pxl_font_file:
  868.  *    Reads font data from file.
  869.  *    If the file is unavailable, its fp is set to NO_FILE.
  870.  *    Returns TRUE unless processing cannot continue.
  871.  */
  872.  
  873. bool
  874. init_pxl_font_file(font_fp, fontptr)
  875. FILE *font_fp;
  876. struct font_entry *fontptr;
  877. {
  878.     int t, i;
  879.     register struct char_entry *tcharptr;
  880.  
  881.     /*
  882.      * Read the PXL file
  883.      */
  884.     if((t = get_unsigned(font_fp, 4)) != PXLID)
  885.     {
  886.         message("Bad font file version %d; font %s.",
  887.           t, fontptr->name);
  888.         fclose(fontptr->font_file_fd);
  889.         fontptr->font_file_fd = NO_FILE;
  890.         return TRUE;
  891.     }
  892.     fseek(font_fp, -20L, 2);
  893.     t = get_unsigned(font_fp, 4);
  894.     if((fontptr->c != 0) && (t != 0) && (fontptr->c != t))
  895.         message("Bad font checksum %d != %d; font %s.",
  896.           t, fontptr->c, fontptr->name);
  897.  
  898.     fontptr->magnification = get_unsigned(font_fp, 4);
  899.     fontptr->designsize = get_unsigned(font_fp, 4);
  900.  
  901.     fseek(font_fp, (long)get_unsigned(font_fp, 4) * 4, 0);
  902.  
  903.     for(i = 0; i < NPXLCHARS; i++)
  904.     {
  905.         tcharptr = &(fontptr->ch[i]);
  906.         tcharptr->width = get_unsigned(font_fp, 2);
  907.         tcharptr->height = get_unsigned(font_fp, 2);
  908.         tcharptr->xOffset= get_signed(font_fp, 2);
  909.         tcharptr->yOffset = get_signed(font_fp, 2);
  910.         tcharptr->where.isloaded = FALSE;
  911.         tcharptr->where.address.fileOffset =
  912.           get_unsigned(font_fp, 4) * 4;
  913.         tcharptr->tfmw =
  914.           ((float)get_unsigned(font_fp, 4)*(float)fontptr->s) /
  915.           (float)(1<<20);
  916.     }
  917.  
  918.     /*
  919.      * Return leaving font file open for access.
  920.      */
  921.     return TRUE;
  922. }
  923.  
  924. static u_char bit_mask[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
  925.  
  926. /*
  927.  * read_font_char:
  928.  *    Reads character from font file.
  929.  *    Returns TRUE unless document cannot be processed.
  930.  */
  931.  
  932. /* ARGSUSED */
  933. bool
  934. read_pxl_font_char(font_fp, fontptr, ptr)
  935. FILE *font_fp;
  936. struct font_entry *fontptr;
  937. register struct char_entry *ptr;
  938. {
  939.     register struct pixrect *pr;
  940.     register int i, j, nints, nbytes, bp;
  941.     u_int buf;
  942.  
  943.     /*
  944.      * Seek to start of char.
  945.      */
  946.     fseek(font_fp, (long)ptr->where.address.fileOffset, 0);
  947.  
  948.     /*
  949.      * Create a mem pixrect.
  950.      * Read the char.
  951.      */
  952.     pr = mem_create(ptr->width, ptr->height, 1);
  953.     nints = (ptr->width + 31) >> 5;
  954.     pr_rop(pr, 0, 0, ptr->width, ptr->height, PIX_CLR, NULL, 0, 0);
  955.     bp = 0;
  956.     for (i=0; i < ptr->height; i++) {
  957.         nbytes = nints * 4;
  958.         for (j=0; j<ptr->width; j++) {
  959.             if(!(bp & 7)) {
  960.                 buf = getc(font_fp);
  961.                 nbytes--;
  962.             }
  963.             pr_put(pr, j, i, (buf & bit_mask[bp&7])?1:0);
  964.             bp++;
  965.         }
  966.         while (nbytes--)
  967.             getc(font_fp);
  968.         bp = 0;
  969.     }
  970.  
  971.     ptr->where.address.pixrectptr = pr;
  972.     ptr->where.isloaded = TRUE;
  973.  
  974.     return TRUE;
  975. }
  976.  
  977. /*
  978.  * PK font reading functions
  979.  */
  980.  
  981. /*  ID byte value at the beginning of PK files  */
  982. #define PK_ID       89
  983.  
  984. /*  PK op codes  */
  985. #define PK_XXX1     240
  986. #define PK_XXX2     241
  987. #define PK_XXX3     242
  988. #define PK_XXX4     243
  989. #define PK_YYY      244
  990. #define PK_POST     245
  991. #define PK_NOP      246
  992. #define PK_PRE      247
  993.  
  994. #define PK_REPEAT   0xe /*  Repeat last row - repeat count in next nibble  */
  995. #define PK_AGAIN    0xf /*  Repeat only once  */
  996. #define PK_LARGE    0x0 /*  Long run vaule coming up  */
  997.  
  998.  
  999. /*
  1000.  * the macros that read pk values need these variables.
  1001.  */
  1002. static u_short    _nyb_buf,
  1003.         _nyb_flag,
  1004.         _pk_repeat;
  1005.  
  1006.  
  1007. /*
  1008.  * get the next nybble of the file.  This macro requires
  1009.  * that 2 integers named _nyb_buf and _nyb_flag be allocated elsewhere in
  1010.  * the program.  In addition, _nyb_flag must be initialized to 0.
  1011.  */
  1012. #define GET_NYB ((_nyb_flag ^= 1) ? \
  1013.             ((_nyb_buf = (unsigned)getc(font_fp)) >> 4) : \
  1014.             (_nyb_buf & 0xf))
  1015.  
  1016. /*
  1017.  * The quantity to be packed into nybbles may require an odd number of
  1018.  * nybbles which will cause the nybble fetching macro to get out of
  1019.  * sync.  The following macro ``clears'' the state of the nybble fetching
  1020.  * routine and should be executed whenever transitioning from nybble to
  1021.  * byte (or other) quantities.
  1022.  */
  1023. #define CLEAR_NYB    _nyb_flag = 0;
  1024.  
  1025. /*
  1026.  * this macro gets a PK ``packed number'' from fp and puts it into x.
  1027.  * It is an adaption of an algorithm presented in Tugboat V. 6, No. 3.
  1028.  */
  1029. #define GET_PACKED(x) x = get_packed(font_fp, dyn_f)
  1030.  
  1031. static u_int
  1032. get_packed(font_fp, dyn_f)
  1033.     register FILE *font_fp;
  1034.     register u_int dyn_f;
  1035. {
  1036.     register int i, j;
  1037.  
  1038.     i = GET_NYB;
  1039.     if (i == 0) {
  1040.         /*    
  1041.          * we have an arbitrarily long number.  scan to
  1042.          * find the first non-zero nybble which is the
  1043.          * count of the nybbles in this value.
  1044.          */
  1045.         do {
  1046.             j = GET_NYB;
  1047.             i++;
  1048.         } while (j == 0);
  1049.  
  1050.         while (--i >= 0)
  1051.             j = (j << 4) + GET_NYB;
  1052.  
  1053.         return (j + 193 - 15 * dyn_f);
  1054.     } else if (i <= dyn_f) {
  1055.         /* this nybble is the number we want. */
  1056.         return (i);
  1057.     } else if (i < 14) {
  1058.         return (i + 15 * (i - dyn_f - 1) + GET_NYB);
  1059.     } else if (i == 14) {
  1060.         _pk_repeat = get_packed (font_fp, dyn_f);
  1061.     } else {
  1062.         _pk_repeat = 1;
  1063.     }
  1064.     return (i);
  1065. }
  1066.  
  1067.  
  1068. bool
  1069. init_pk_font_file (font_fp, fontptr)
  1070.     register FILE *font_fp;
  1071.     register struct font_entry *fontptr;
  1072. {
  1073.     register unsigned c, cc;
  1074.     long pl, addr;
  1075.     register u_int i;
  1076.     u_int hppp, vppp;
  1077.     int checksum;
  1078.     u_int tfmw;
  1079.     double cscale;
  1080.  
  1081.     fseek (font_fp, 0L, 0);    /* make sure at the beginning of pk file */
  1082.  
  1083.     if (get_unsigned(font_fp, 1) != PK_PRE) {
  1084.         message("pk font file %s doesn't start with PRE\n",
  1085.              fontptr->name);
  1086.         fclose(fontptr->font_file_fd);
  1087.         fontptr->font_file_fd = NO_FILE;
  1088.         return TRUE;
  1089.     }
  1090.  
  1091.     if (get_unsigned(font_fp, 1) != PK_ID) {
  1092.         message("pk font file %s wrong version\n",
  1093.              fontptr->name);
  1094.         fclose(fontptr->font_file_fd);
  1095.         fontptr->font_file_fd = NO_FILE;
  1096.         return TRUE;
  1097.     }
  1098.  
  1099.     fseek (font_fp, (long) get_unsigned(font_fp, 1), 1);    /* skip comment */
  1100.     fontptr->designsize = get_unsigned(font_fp, 4);    /* ds[4] */
  1101.     checksum = get_unsigned(font_fp, 4);    /* checksum[4] */
  1102.     hppp = get_unsigned(font_fp, 4);        /* hppp[4] */
  1103.     vppp = get_unsigned(font_fp, 4);        /* vppp[4] */
  1104.     cscale = (double) fontptr->s / (double)(1 << 20);
  1105.  
  1106.     while ((c = get_unsigned(font_fp, 1)) != EOF) {
  1107.         if (c >= PK_XXX1) {    /* commands are just skipped */
  1108.             switch (c) {
  1109.             case PK_XXX1:    /* pk_xxx1 k[1] x[k] */
  1110.                 fseek (font_fp, (long)get_unsigned(font_fp,1), 1);
  1111.                 break;
  1112.             case PK_XXX2:    /* pk_xxx2 k[2] x[k] */
  1113.                 fseek (font_fp, (long)get_unsigned(font_fp,2), 1);
  1114.                 break;
  1115.             case PK_XXX3:    /* pk_xxx3 k[3] x[k] */
  1116.                 fseek (font_fp, (long)get_unsigned(font_fp,3), 1);
  1117.                 break;
  1118.             case PK_XXX4:    /* pk_xxx4 k[4] x[4] */
  1119.                 fseek (font_fp, (long)get_signed(font_fp,4), 1);
  1120.                 break;
  1121.             case PK_YYY:    /* pk_yyy y[4] */
  1122.                 (void) get_unsigned(font_fp, 4);
  1123.                 break;
  1124.             case PK_POST:
  1125.                 return TRUE;
  1126.             case PK_PRE:
  1127.                 message("pk font file %s has extra PRE\n",
  1128.                     fontptr->name);
  1129.                 fclose(fontptr->font_file_fd);
  1130.                 fontptr->font_file_fd = NO_FILE;
  1131.                 return TRUE;
  1132.             default: /* do nothing */ ;
  1133.             }
  1134.         } else {    /* flag byte */
  1135.             switch (c & 0x07) {    /* check flag byte */
  1136.             case 0:/* short form */
  1137.             case 1:
  1138.             case 2:
  1139.             case 3:
  1140.                 /* length */
  1141.                 pl = (long) get_unsigned(font_fp, 1)
  1142.                      + (long) ((c & 0x03) << 8);
  1143.                 cc = get_unsigned(font_fp,1);    /* char. code */
  1144.                 tfmw = get_unsigned(font_fp,3); /* tfm width */
  1145.                 (void) get_unsigned(font_fp,1); /* x-escapement */
  1146.                 fontptr->ch[cc].width = get_unsigned(font_fp, 1);
  1147.                 fontptr->ch[cc].height = get_unsigned(font_fp, 1);
  1148.                 fontptr->ch[cc].xOffset = get_signed(font_fp, 1);
  1149.                 fontptr->ch[cc].yOffset = get_signed(font_fp, 1);
  1150.                 addr = ftell (font_fp);
  1151.                 pl -= 8;
  1152.                 break;
  1153.  
  1154.             case 4:/* extended short form */
  1155.             case 5:
  1156.             case 6:
  1157.                 pl = (long) get_unsigned(font_fp, 2)
  1158.                      + (long) ((c & 0x03) << 16);
  1159.                 cc = get_unsigned(font_fp,1);    /* char. code */
  1160.                 tfmw = get_unsigned(font_fp,3); /* tfm width */
  1161.                 (void) get_unsigned(font_fp,2); /* x-escapement */
  1162.                 fontptr->ch[cc].width = get_unsigned(font_fp, 2);
  1163.                 fontptr->ch[cc].height = get_unsigned(font_fp, 2);
  1164.                 fontptr->ch[cc].xOffset = get_signed(font_fp, 2);
  1165.                 fontptr->ch[cc].yOffset = get_signed(font_fp, 2);
  1166.                 addr = ftell (font_fp);
  1167.                 pl -= 13;
  1168.                 break;
  1169.  
  1170.             case 7:/* long form */
  1171.                 pl = get_unsigned(font_fp,4);
  1172.                 cc = get_unsigned(font_fp,4);    /* char. code */
  1173.                 tfmw = get_unsigned(font_fp,4);
  1174.                 (void) get_unsigned(font_fp,4); /* x-escapement */
  1175.                 fontptr->ch[cc].width = get_unsigned(font_fp, 4);
  1176.                 fontptr->ch[cc].height = get_unsigned(font_fp, 4);
  1177.                 fontptr->ch[cc].xOffset = get_signed(font_fp, 4);
  1178.                 fontptr->ch[cc].yOffset = get_signed(font_fp, 4);
  1179.                 addr = ftell (font_fp);
  1180.                 pl -= 24;
  1181.                 break;
  1182.             }
  1183.             fontptr->ch[cc].tfmw = (int)(((double)tfmw * cscale) + 0.5);
  1184.             fontptr->ch[cc].where.isloaded = 0;
  1185.             fontptr->ch[cc].where.flags = c;
  1186.             fontptr->ch[cc].where.address.fileOffset = addr;;
  1187.             fseek (font_fp, pl, 1);    /* skip until next flag byte */
  1188.         }
  1189.     }
  1190.     if((fontptr->c != 0) && (checksum != 0) && (fontptr->c != checksum))
  1191.         message("Bad font checksum %d != %d; font %s.",
  1192.           checksum, fontptr->c, fontptr->name);
  1193.     return TRUE;
  1194. }
  1195.  
  1196.  
  1197. /*
  1198.  * load a PK character into memory.
  1199.  */
  1200. bool
  1201. read_pk_font_char(font_fp, fontptr, ptr)
  1202.     register FILE *font_fp;
  1203.     register struct font_entry *fontptr;
  1204.     register struct char_entry *ptr;
  1205. {
  1206.     register struct pixrect *pr;
  1207.     int    cw;    /* character width */
  1208.     int    ch;    /* character height */
  1209.     u_int    dyn_f;    /* dynamic factor, part of a PK word. */
  1210.     register int i, j;
  1211.     register int black, bits, bp, rc;
  1212.     int    rowp;
  1213.  
  1214.     if (ptr->width == 0 || ptr->height == 0) {
  1215.         ptr->where.address.pixrectptr = (struct pixrect *) 0;
  1216.         return;
  1217.     }
  1218.     fseek(font_fp, (long)ptr->where.address.fileOffset, 0);
  1219.  
  1220.     pr = mem_create(ptr->width, ptr->height, 1);
  1221.     ptr->where.address.pixrectptr = pr;
  1222.  
  1223.     cw = ptr->width; ch = ptr->height;
  1224.     pr_rop(pr, 0, 0, cw, ch, PIX_CLR, NULL, 0, 0);
  1225.  
  1226.     /*
  1227.      * what remains is the data for the image.  It can be packaged
  1228.      * either as a run-encoding where successive values are the
  1229.      * number of adjacent pixels to paint in the opposite color of
  1230.      * the previous painting, or simply as a bitmap with no padding
  1231.      * except (possibly) for the very last nybble to round up to a
  1232.      * byte value.
  1233.      *
  1234.      * the data for the character is stored in successive bits with
  1235.      * each new horizontal row at a long boundary.  See the PXL
  1236.      * file format.
  1237.      */
  1238.  
  1239.     /*
  1240.      * grab the dyn_f out of the flag for this character.
  1241.      */
  1242.     dyn_f = (ptr->where.flags >> 4) & 0xf;
  1243.     /*
  1244.      * the data returned by calloc is zeroed; we depend on that
  1245.      * because we only turn on bits that are supposed to be
  1246.      * black.
  1247.      */
  1248.     if (dyn_f == 14) {
  1249.         /*
  1250.          * we have a bitmap rather than a run-encoding.
  1251.          */
  1252.         u_int buf;
  1253.         bp = 0;
  1254.         for (i=0; i < ch; i++) {
  1255.             for (j=0; j<cw; j++) {
  1256.                 if(!(bp & 7))
  1257.                     buf = getc(font_fp);
  1258.                 pr_put(pr, j, i, (buf & bit_mask[bp&7])?1:0);
  1259.                 bp++;
  1260.             }
  1261.         }
  1262.     } else {
  1263.         bp = _pk_repeat = rc = rowp = 0;
  1264.         black = ptr->where.flags & (1 << 3);
  1265.         bits = cw * ch;
  1266.         CLEAR_NYB;
  1267.         while (bp < bits) {
  1268.             GET_PACKED(j);
  1269.             
  1270.             if (_pk_repeat != 0) {
  1271.                 rc = _pk_repeat;
  1272.                 rowp = bp / cw;
  1273.                 _pk_repeat = 0;
  1274.                 continue;
  1275.             }
  1276.             
  1277.             /*
  1278.              * we have a run count in j.
  1279.              */
  1280.             if (black) {
  1281.                 register int k,l,m;
  1282.                 
  1283.                 l = bp / cw;            /* starting row */
  1284.                 m = (bp + j) / cw;      /* ending row */
  1285.                 k = bp % cw;        /* start bit offset */
  1286.                 i = (bp + j) % cw;    /* ending bit offset */
  1287.  
  1288.                 if (j <= cw && (k < i || i == 0)) {
  1289.                     /* we're changing less than a row */
  1290.                     pr_rop(pr, k, l, j, 1, PIX_SET,
  1291.                            NULL, 0, 0);
  1292.                 } else {
  1293.                     /* fill any fragment in the current row */
  1294.                     pr_rop(pr, k, l, cw-k, 1, PIX_SET,
  1295.                            NULL, 0, 0);
  1296.  
  1297.                     /* fill some number of full rows */
  1298.                     pr_rop(pr, 0, l+1, cw, (j-(cw-k))/cw,
  1299.                            PIX_SET, NULL, 0, 0);
  1300.  
  1301.                     /* fill any fragment in the last row */
  1302.                     if (i)
  1303.                         pr_rop(pr, 0, m, i, 1, PIX_SET,
  1304.                                NULL, 0, 0);
  1305.                 }
  1306.             }
  1307.             bp += j;
  1308.             
  1309.             /*
  1310.              * if there's a repeat count and we hit the end of
  1311.              * a row, do the copy.
  1312.              */
  1313.             if (rc && (bp - (rowp*cw)) >= cw) {
  1314.                 i = rowp+1;
  1315.                 j = rowp+1+rc;
  1316.                 if ((i*cw) != bp) {
  1317.                     pr_rop(pr, 0, j, cw, 1, PIX_SRC,
  1318.                            pr, 0, i);
  1319.                 }
  1320.                 j = rc;
  1321.                 while(j--) {
  1322.                     pr_rop(pr, 0, i, cw, 1, PIX_SRC,
  1323.                            pr, 0, rowp);
  1324.                     i++;
  1325.                 }
  1326.                 bp += rc * cw;
  1327.                 rc = 0;
  1328.             }
  1329.             black = !black;
  1330.         }
  1331.     }
  1332.  
  1333.     ptr->where.isloaded = TRUE;
  1334.     return TRUE;
  1335. }
  1336.